package cn.itsource.ymcc.service.impl;

import cn.itsource.result.JSONResult;
import cn.itsource.util.AssertUtil;
import cn.itsource.util.BitStatesUtils;
import cn.itsource.ymcc.constance.RedisConstant;
import cn.itsource.ymcc.domain.Login;
import cn.itsource.ymcc.domain.User;
import cn.itsource.ymcc.domain.UserAccount;
import cn.itsource.ymcc.domain.UserBaseInfo;
import cn.itsource.ymcc.dto.RedisSMSCodeValueDTO;
import cn.itsource.ymcc.dto.UserRegisterDTO;
import cn.itsource.ymcc.feign.UaaFeignClient;
import cn.itsource.ymcc.mapper.UserAccountMapper;
import cn.itsource.ymcc.mapper.UserBaseInfoMapper;
import cn.itsource.ymcc.mapper.UserMapper;
import cn.itsource.ymcc.service.IUserService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author Cherish
 * @since 2022-08-05
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private  UserMapper userMapper;


    @Autowired
    private UserBaseInfoMapper userBaseInfoMapper;

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private UaaFeignClient uaaFeignClient;


    private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();





    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(UserRegisterDTO dto) {
         /*
        2.参数判断
	        mobile---查数据库  有没有这个手机号
			    有  抛异常

         */
        EntityWrapper<User> wrapper = new EntityWrapper<>();

        //where phone = #{phone}
        //= equals
        wrapper.eq("phone", dto.getMobile());
        List<User> userList = userMapper.selectList(wrapper);
        boolean existUser = userList!=null&&userList.size()>0;
        AssertUtil.isFalse(existUser, "用户已注册");


        /*
        smsCode---到redis里面去查  看是不是一样
			    如果不一样  抛异常
         */

        String key = RedisConstant.REDIS_SMS_CODE_PREFIX + dto.getMobile();

        RedisSMSCodeValueDTO redisSMSCodeValueDTO =
                (RedisSMSCodeValueDTO)redisTemplate.opsForValue().get(key);

        AssertUtil.isNotNull(redisSMSCodeValueDTO,"没有找到验证码");
        boolean checkSMSCode = StringUtils.equals(redisSMSCodeValueDTO.getCode(), dto.getSmsCode());
        AssertUtil.isTrue(checkSMSCode,"验证码错误");

        /*
        因为user需要存loginId  所以先存login表
      		存好之后需要给我一个loginId
         */
        Login login = new Login();
        login.setUsername(dto.getMobile());
        login.setPassword(passwordEncoder.encode(dto.getPassword()));
        login.setType(dto.getRegChannel());
        //TODO 有几个字段需要确认
        //TODO 需要写login插入
        JSONResult loginSaveResult = uaaFeignClient.saveOrUpdate(login);
        Object data = loginSaveResult.getData();
        //String parse = (String)JSON.parse(loginJson);
        //Login loginResult = JSONObject.parseObject(parse, Login.class);
        //Long loginId = loginResult.getId();
        Long loginId = Long.valueOf(String.valueOf(data));



        /*
        保存user相关的表
	        user
	        user-base-info
	        user-account
         */


        //============保存User对象  start===================
        User user = new User();
        user.setPhone(dto.getMobile());
        user.setCreateTime(new Date().getTime());
        user.setNickName(dto.getMobile());
        Long states = BitStatesUtils.batchAddState(0L,
                BitStatesUtils.OP_REGISTED,
                BitStatesUtils.OP_ACTIVED,
                BitStatesUtils.OP_AUTHED_PHONE

        );
        user.setBitState(states);
        user.setLoginId(loginId);
        userMapper.insert(user);
        //============保存User对象  end===================


        //============保存UserBaseInfo对象  start===================
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setId(user.getId());
        userBaseInfo.setCreateTime(user.getCreateTime());
        userBaseInfo.setRegChannel(dto.getRegChannel());
        userBaseInfoMapper.insert(userBaseInfo);
        //============保存UserBaseInfo对象  end===================


        //============保存UserBaseInfo对象  start===================
        UserAccount userAccount = new UserAccount();
        userAccount.setId(user.getId());
        userAccount.setCreateTime(user.getCreateTime());
        userAccountMapper.insert(userAccount);
        //============保存UserBaseInfo对象  end===================



        //删除redis中对应的手机验证码
        redisTemplate.delete(key);
    }


}
